﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;

namespace WPAChess
{
    using System.Collections.Generic;

	public partial class ChessBoard : UserControl
	{
        private Square[][] squares = new Square[8][];
        private List<Piece> pieces = new List<Piece>();

        private Position position;
         
        private PiecesFactory piecesFactory = new PiecesFactory();

        //public delegate void AnimationCompletedHandler();
        //public event AnimationCompletedHandler AnimationCompleted;

		public ChessBoard()
		{
			// Required to initialize variables
			InitializeComponent();

            // chia va hien thi o co len ban co
            for (byte row = 0; row < 8; ++row)
            {
                //dinh nghia chieu rong o co
                RowDefinition rowDefinition = new RowDefinition();
                rowDefinition.Height = new GridLength(1.0/8.0, GridUnitType.Star);
                this.LayoutRoot.RowDefinitions.Add(rowDefinition);

                // dinh nghia chieu cao
                ColumnDefinition columnDefinition = new ColumnDefinition();
                columnDefinition.Width = new GridLength(1.0/8.0, GridUnitType.Star);
                this.LayoutRoot.ColumnDefinitions.Add(columnDefinition);

                this.squares[row] = new Square[8];

                for (byte col = 0; col < 8; ++col)
                {
                    this.squares[row][col] = new Square(this, row, col);
                }
            }

            this.LayoutUpdated += OnChessBoardLayoutUpdated;

             
		}


        //private int currentAnimation = 0;

        /// <summary>
        /// thuc hien viec tao piece
        /// </summary>
        /// <param name="type"></param>
        /// <returns>Piece</returns>
        public Piece GenerationPiece(byte type)
        {
            Piece piece = this.piecesFactory.CreatePiece(type);
            if (piece != null)
            {
                piece.Opacity = 0;
                this.LayoutRoot.Children.Add(piece);

            }

            this.pieces.Add(piece);

            return piece;

        }


        public delegate void AnimationCompletedHandler();
        public event AnimationCompletedHandler AnimationCompleted;
         

        private int currentAnimation = 0;

        public void AddPiecesToChessBoard()
        {
            const int duration = 400; 

            Storyboard animation = new Storyboard();
            animation.Duration = TimeSpan.FromMilliseconds(duration + 25);
            this.Resources.Add("Timline" + this.currentAnimation++, animation);

            for (int i = 0; i < this.position.pieceList.Length; i++)
            {


                Location newPieceLocation = this.position.pieceList[i];


                Piece newPiece = newPieceLocation != null ? this.GenerationPiece(this.position.Board[newPieceLocation.Row][newPieceLocation.Column]) : null;
               

                DoubleAnimation opacityAnimation = new DoubleAnimation();
                Storyboard.SetTarget(opacityAnimation, newPiece);
                Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath("Opacity"));
                opacityAnimation.Duration = TimeSpan.FromMilliseconds(duration);
                opacityAnimation.To = 1;

                newPiece.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e)
                {
                    this.OnSquareClicked(newPieceLocation.Row, newPieceLocation.Column);
                };

                Grid.SetRow(newPiece, newPieceLocation.Row);
                Grid.SetColumn(newPiece, newPieceLocation.Column);

                animation.Children.Add(opacityAnimation);
               

            } 
            // Workaround layout bug.
            this.LayoutRoot.Width--;
            this.LayoutRoot.Height++;

            animation.Completed += this.OnAnimationCompleted;
            animation.Begin();

        }











        private void OnAnimationCompleted(object sender, EventArgs e)
        {
            if (this.AnimationCompleted != null)
            {
                this.AnimationCompleted();
            }
        }


        protected override Size ArrangeOverride(Size finalSize)
        {
            double size = Math.Min(finalSize.Width, finalSize.Height);
            return base.ArrangeOverride(new Size(size, size));
        }
        
        public Position Position
        {
            get { return this.position; }
            set
            {
                this.position = value; 
                AddPiecesToChessBoard();
                 
            }
        }

        private void OnChessBoardLayoutUpdated(object sender, EventArgs e)
        { 
            this.UpdatePieceSizes();
        }


         /// <summary>
         /// canh kich thuoc cua quan co voi o co
         /// </summary>
        private void UpdatePieceSizes()
        {
            double size = (this.ActualWidth / 8) / 100; //ti le 0.6

            for (int i = 0; i < this.pieces.Count; i++)
            {
                if (this.pieces[i] != null)
                {
                    TransformGroup group = new TransformGroup();
                    TranslateTransform translate = new TranslateTransform();
                    translate.X = 0;
                    translate.Y = 0;
                    group.Children.Add(translate);
                    ScaleTransform scale = new ScaleTransform();
                    scale.ScaleX = size;
                    scale.ScaleY = size;
                    group.Children.Add(scale);
                    this.pieces[i].RenderTransform = group; // 0.6/1
                }
            }
        }

        

        private Location prevSquareSelected = null;

        public void OnSquareClicked(byte row, byte col)
        {
            byte pieceValue = this.position.Board[row][col];
            byte prevPieceValue = 0xFF;
            if (this.prevSquareSelected != null) { prevPieceValue = this.position.Board[this.prevSquareSelected.Row][this.prevSquareSelected.Column]; }

            if (this.prevSquareSelected == null)
            {
                if (pieceValue != Pieces.empty)
                {
                    if ((pieceValue & Pieces.white) == this.position.ToMove)
                    {
                        this.squares[row][col].HighLight = true;
                        this.prevSquareSelected = new Location(row, col);
                    }
                }
            }
            else  
            {
                //deselected
                if (pieceValue == prevPieceValue)
                {
                    this.squares[row][col].HighLight = false;
                    this.prevSquareSelected = null;
                } 
            }

            
        }

	}

}